package service

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/robfig/cron"
	"log"
	"service/basic/config"
	__ "service/basic/proto"
	"service/handler/model"
	"service/untils"
	"strconv"
	"time"
)

// 接单
func (s *Server) CleanerAdd(_ context.Context, in *__.CleanerAddReq) (*__.CleanerAddResp, error) {
	var order model.Order
	order.Id = uint(in.OrderId)
	//查找订单
	if err := order.Detail(); err != nil {
		return nil, errors.New("订单信息查找失败")
	}
	//设置分布式锁
	lockKey := fmt.Sprintf("lock_order:%d", in.CleanerId)
	lockId := uuid.NewString()
	result, err := config.Rdb.SetNX(config.Ctx, lockKey, lockId, time.Hour).Result()
	if err != nil {
		return nil, errors.New("上锁失败")
	}
	if !result {
		return nil, errors.New("同一时间保洁师只能接一个订单")
	}

	//接单
	order.CleanerId = uint(in.CleanerId)
	if err := order.UpdateToCleanerId(); err != nil {
		return nil, errors.New("接单失败")
	}
	//接单后修改订单状态
	if err := order.UpdateToStatus(); err != nil {
		return nil, errors.New("订单状态修改失败")
	}

	//调用定时任务
	//CronOrder(int64(order.Id), int64(order.PayStatus))
	//释放锁
	//defer DelLock(int(order.CleanerId))

	return &__.CleanerAddResp{
		Id:          int64(order.Id),
		OrderNo:     order.OrderNo,
		UserId:      int64(order.UserId),
		CleanerId:   int64(order.CleanerId),
		Address:     order.Address,
		CleanerAre:  int64(order.CleanerAre),
		Diff:        int64(order.Diff),
		CleanerType: order.OrderNo,
		PriceCount:  int64(order.PriceCount),
	}, nil
}

// 拒单
func (s *Server) CleanerRemove(_ context.Context, in *__.CleanerRemoveReq) (*__.CleanerRemoveResp, error) {
	var order model.Order
	order.Id = uint(in.OrderId)
	//查找订单
	if err := order.Detail(); err != nil {
		return nil, errors.New("订单信息查找失败")
	}
	//拒单
	order.CleanerId = uint(in.CleanerId)
	if err := order.UpdateNoCleanerId(); err != nil {
		return nil, errors.New("拒单失败")
	}
	//接单后修改订单状态
	if err := order.UpdateNoStatus(); err != nil {
		return nil, errors.New("订单状态修改失败")
	}

	return &__.CleanerRemoveResp{
		Message: "保洁员因距离原因拒绝接单",
	}, nil
}

// 定时任务
func CronOrder(orderId, payStatus int64) {
	c := cron.New()
	spec := "* * */24 * * ?"
	err := c.AddFunc(spec, func() {
		var order model.Order
		order.Id = uint(orderId)
		order.PayStatus = uint(payStatus)
		//查找未支付的订单
		err := order.GetOrderPayStatus()
		if err != nil {
			log.Println("订单查找失败")
		}
		//将位置付的订单状态改为待接单
		err = order.UpdateNoStatus()
		if err != nil {
			log.Println("订单状态修改失败")
		}
	})
	fmt.Println(err)
	c.Start()

	select {}
}

func DelLock(cleanerId int) {
	lockKey := fmt.Sprintf("lock_order:%d", cleanerId)
	//lua脚本保证redis的一致性
	script := `
	if redis.coll("get", KEYS[1]) == ARGV[1] then
		return redis.coll("del", KEYS[1])
	else
		return 0
	end
	`
	config.Rdb.Eval(config.Ctx, script, []string{lockKey}, cleanerId)
}

// 验证顾客身份
func (s *Server) UserMobile(_ context.Context, in *__.UserMobileReq) (*__.UserMobileResp, error) {
	var order model.Order
	order.Id = uint(in.OrderId)
	if err := order.Detail(); err != nil {
		return nil, errors.New("订单查询失败")
	}
	var user model.User
	user.Id = order.UserId
	if err := user.GetUserInfoByMobile(); err != nil {
		return nil, errors.New("用户手机号查询失败")
	}
	if in.Mobile != "3792" {
		return &__.UserMobileResp{
			Message: "身份验证失败",
		}, nil
	}
	return &__.UserMobileResp{
		Message: "身份验证成功",
	}, nil
}

// 订单结算
func (s *Server) OrderEnd(_ context.Context, in *__.OrderEndReq) (*__.OrderEndResp, error) {
	var order model.Order
	order.Id = uint(in.OrderId)
	if err := order.Detail(); err != nil {
		return nil, errors.New("订单价格查询失败")
	}
	//调用支付宝支付
	pay := untils.ZhiFuBao{}
	outTradeNo := uuid.NewString()
	totalAmount := order.PriceCount
	pauUrl := pay.Payment(outTradeNo, strconv.Itoa(int(totalAmount)))

	//实例化rabbitmq
	rabbitmq := untils.NewRabbitMQSimple(untils.MQURL)
	_, err := rabbitmq.PublishSimple(order.OrderNo)
	if err != nil {
		return nil, errors.New("消息发送失败")
	}
	log.Println("订单支付成功")

	//修改订单支付状态
	if err := order.UpdateNoPayStatus(); err != nil {
		return nil, errors.New("订单状态修改失败")
	}

	return &__.OrderEndResp{
		Price:  int64(order.PriceCount),
		PayUrl: pauUrl,
	}, nil
}
